<?php

class RouterException extends Exception {

	const wrong_base_url = 10;
	const generic_router_error = 20;
	const router_no_exception = 30;
}

class Router {
	
	public $module = '';
	public $action;
	public $entitiy;
	public $routing_error = false;
	
	private $url_params;
	
	function __construct(){
		try{
			$this->url_params = self::parse_qsu();
			$this->route();
			fb($this);
		}catch(RouterException $e){
			$this->routing_error = $e;
		}
	}
	
	private function route(){
		if(!empty($this->url_params)){
			$url_params = array_filter(explode('/', $this->url_params));
			$nr = count($url_params) - 1;
			$last_element = self::get_last_element($url_params, $nr);
			if(strpos($last_element, FILE_ACTION_EXTENSION) !== false){
				$this->action = substr($last_element, 0,strlen(FILE_ACTION_EXTENSION)-1);
				unset($url_params[$nr]);
			}elseif(strpos($last_element, FILE_ENTITY_EXTENSION) !== false){
				$this->entity = substr($last_element, 0,strlen(FILE_ENTITY_EXTENSION)-1);
				unset($url_params[$nr]);
			} else {
				$this->action = '';
			}
			for($i = 0; $i < $nr; $i++){
				$this->module.= $url_params[$i];
				if(($i+1) < $nr)$this->module.= '_';
			}
			if(empty($this->action) && !$this->read_map($last_element)){
				$this->module = empty($this->module) ? $last_element : '_'.$last_element;
			}
		}
	}
	
	private static function parse_qsu(){
		$requestURL = self::get_full_url();
		if(self::control_defined_url_logic($requestURL)){
			return substr($requestURL, strlen(BASE_URL));
		} else {
			throw new RouterException('Wrong_base_url_configuration', RouterException::wrong_base_url);
		}
	}
	
	private static function get_full_url(){
		$s = empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : "";
		$sp = strtolower($_SERVER["SERVER_PROTOCOL"]);
		$protocol = substr($sp, 0, strpos($sp, "/")) . $s;
		$port = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":".$_SERVER["SERVER_PORT"]);
		return $protocol . "://" . $_SERVER['SERVER_NAME'] . $port . $_SERVER['REQUEST_URI'];
	}
	
	private static function control_defined_url_logic($uri){
		if(strpos($uri, BASE_URL)!== false){
			return true;
		} else {
			return false;
		}
	}
	
	private static function get_last_element($params, $nr){
		$last_element = $params[$nr];
		if(strpos($last_element, '?') !== false){
			$last_element = $params[$nr-1];
			unset($params[$nr]);
		}
		return $last_element;
	}
	
	private function read_map($last_element){
		if(defined("MVC_ACTIONS_MAP")){
			include(CONFIG_DIR.MVC_ACTIONS_MAP);
			if(isset($map)){
				$module = empty($this->module) ? 'index' : $this->module;
				if(array_key_exists($module, $map)){
					if(array_key_exists($last_element, $map[$module])){
						$this->action = !empty($map[$module][$last_element]) ? $map[$module][$last_element] : 'index';
						return true;
					}
				}
			}
		}
		return false;
	}
}